import React, { Component } from 'react'
import intl from 'react-intl-universal'
import { httpPost } from '../../services/http'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { LOGIN_USER } from '../../constants/user'
import { connect } from 'react-redux'
import MyJumbotron from '../../components/MyJumbotron/MyJumbotron'
import SpinnerButton from '../../components/SpinnerButton/SpinnerButton'
import {
  Alert,
  Button,
  Card,
  Col,
  Container,
  Form,
  FormControl,
  InputGroup,
  Row
} from 'react-bootstrap'
// 注意引入formik的方式
import { Formik } from 'formik'
// 引入yup的方式
import * as yup from 'yup'

class Login extends Component {
  state = { flag: true, show: false, err: null }

  submit = async (...aru) => {
    const { dispatch, history } = this.props
    const formData = aru[0]
    this.setState({ flag: false })
    const [res, err] = await httpPost({ url: '/user/login', data: formData })
    if (res) {
      const token = res.data.token
      window.localStorage.setItem('token', token)
      dispatch({ type: LOGIN_USER })
      history.goBack()
    } else {
      this.setState({ flag: true, show: true, err: err })
    }
  }

  render () {
    const enter = {
      'email': intl.get('enter', { inputType: intl.get('email') }),
      'password': intl.get('enter', { inputType: intl.get('password') })
    }
    // yup.object()表示是一个对象  shape()用来形容它的形状 也就是它的属性组成
    // * 我们这里使用formik与yup完成验证
    const schema = yup.object().shape({
      email: yup.string().required(enter.email),
      password:
        yup.string().trim().min(6, intl.get('less', { length: 6 })).
          max(20, intl.get('more', { length: 20 })).
          required(enter.password)
    })
    return (
      <>
        <MyJumbotron />

        <Container>
          <Row className = {'justify-content-center'}>
            <Col xs = {10} sm = {8} md = {6} lg = {4}>
              <Card>
                <Card.Body>
                  {/*
                    * 注意这里的使用方法 Formik 组件只是 formik依赖的一个组件 还有其他的可以去官方文档看
                    * Formik 有很多属性可以看源码
                   */}
                  <Formik
                    // 这里相当于是验证规则
                    validationSchema = {schema}
                    // 提交的函数
                    onSubmit = {this.submit}
                    // 这里是初始化的值
                    initialValues = {{
                      email: '1991525233@qq.com',
                      password: '361230312.,'
                    }}
                  >
                    {
                      ({
                        handleSubmit,
                        handleChange,
                        handleBlur,
                        // 这里就相当于是上面Formik的initialValues
                        values,
                        // 默认的字段信息 用于做提示
                        touched,
                        // 是否全部通过验证
                        isValid,
                        // 没有通过验证
                        errors
                      }) => {
                        return (
                          <Form noValidate
                                onSubmit = {handleSubmit}>
                            {
                              // 这是错误提示
                              this.state.err
                                ? <Alert variant = {'danger'}
                                         dismissible
                                         onClose = {() => this.setState(
                                           { show: false })}
                                         show = {this.state.show}>
                                  {intl.get(this.state.err.msg,
                                    { name: intl.get(this.state.err.name) })}
                                </Alert>
                                : null
                            }
                            {/* 邮箱 */}
                            <Form.Group>
                              <InputGroup hasValidation>
                                <InputGroup.Prepend>
                                  <InputGroup.Text id = "email">
                                    <FontAwesomeIcon
                                      icon = "envelope-open-text" />
                                  </InputGroup.Text>
                                </InputGroup.Prepend>
                                <FormControl
                                  type = "email"
                                  name = {'email'}
                                  value = {values.email}
                                  placeholder = {enter.email}
                                  aria-describedby = "email"
                                  // 注意 这里的这个onChange必须要有 不然就不能修改 这里相当于实现了双向绑定
                                  onChange = {handleChange}
                                  // isValid 这个属性是通过验证时显示的
                                  // isValid = {touched.email && !errors.email}
                                  // isInvalid 这个属性时验证失败时显示的  这里两次取反只是为了将它转换为Boolean形式不是多此一举
                                  isInvalid = {!!errors.email}
                                />
                                <FormControl.Feedback type = {'invalid'}>
                                  {errors.email}
                                </FormControl.Feedback>
                              </InputGroup>
                            </Form.Group>
                            {/* 密码 */}
                            <Form.Group>
                              <InputGroup hasValidation>
                                <InputGroup.Prepend>
                                  <InputGroup.Text id = "basic-addon2">
                                    <FontAwesomeIcon icon = "lock" />
                                  </InputGroup.Text>
                                </InputGroup.Prepend>
                                <FormControl
                                  name = {'password'}
                                  value = {values.password}
                                  onChange = {handleChange}
                                  isInvalid = {!!errors.password}
                                  type = "password"
                                  placeholder = {enter.password}
                                  aria-describedby = "basic-addon2"
                                />
                                <FormControl.Feedback type = {'invalid'}>
                                  {errors.password}
                                </FormControl.Feedback>
                              </InputGroup>
                            </Form.Group>
                            {/* 登录按钮 */}
                            <Form.Group>
                              {
                                this.state.flag ? <Button
                                  style = {{ width: '100%' }}
                                  type = "submit">
                                  {intl.get('log in')}</Button> : <SpinnerButton
                                  style = {{ width: '100%' }}>
                                  {intl.get('log in')}...
                                </SpinnerButton>
                              }
                            </Form.Group>
                            {/* 注册按钮 */}
                            <Form.Group>
                              <Button style = {{ width: '100%' }}
                                      onClick = {() => {
                                        this.props.history.push('/register')
                                      }}
                                      variant = "info">{intl.get(
                                'register')}</Button>
                            </Form.Group>
                          </Form>
                        )
                      }
                    }
                  </Formik>
                </Card.Body>
              </Card>
            </Col>
          </Row>
        </Container>
      </>
    )
  }
}

export default connect()(Login)
